昨天介紹了 Next.js 13 改版三大核心的第一點 - Compiler Infrastructure 的優化,今天繼續來認識下一個重點:Rendering Infrastructure 的優化!
在開始前做個小提醒,因為個人習慣使用 TypeScript,等等假如看到 .ts/.tsx
的副檔名,不習慣使用 TypeScript 的朋友可自動轉成 .js/.jsx
!
在去年五月底的 RFC ( Request for Comment ) 中,Next 團隊提到,這段時間他們持續在 GitHub、Discord、Reddit 等社群搜集關於 routing system 的意見回饋,並得出了一個優化方向:提供更簡單且功能更豐富的 routing 機制,以及可巢狀、跨路由且保留 state 的 layouts。
The developer experience of creating layouts can be improved. It should be easy to create layouts that can be nested, shared across routes, and have their state preserved on navigation.
Many Next.js applications are dashboards or consoles, which would benefit from more advanced routing solutions.
因此團隊決定結合 React 18 推出的新功能 ( Streaming、Transitions、Suspense ),以及 2020 推出的 React Server Components,開發出一套,能讓開發者能以更簡單的方式來使用這些新功能,達成上述目標的架構。App Router ( App Directory ) 便就此誕生!
現在進入 Next 官網的 Docs 區,你會發現頁面左上角多了一個下拉選單,可以選擇要閱讀 App Router 或是 Pages Router 的教學文件。
( 圖片來源:https://nextjs.org/docs/app )
究竟什麼是 App Router 跟 Pages Router 呢?
簡單來說,它們是 Next 開發的兩套路由架構。Next.js 其中一個便利的設計就在於它的 routing 系統。假如你用過 React 開發 SPA (Single Page Applications),可能會使用像 React Router 這類的 library 來設定不同 path 對應到不同 components。當專案規模較大時,路由的巢狀結構也會隨之複雜,開發上麻煩也容易出錯。
而 Next.js 則是使用 file-system based router,意思是路由會根據專案的檔案結構自動被定義,不需額外去做設定。App Router 推出前,都是遵循 Pages Router 的規則來定義路由:專案中會有一個 pages 資料夾,Next 會根據裡面的 .js/.jsx/.ts/.tsx
檔案檔名,或是資料夾中的 index.tsx
生成 route segment。
比方說,/pages/about.tsx
定義的 UI 就會顯示在 /about 中;/pages/notes/index.tsx
會出現在 /notes 中;/pages/blog/first-post.tsx
會出現在 /blog/first-post 中。
( 圖片來源:https://blog.logrocket.com/next-js-routechangestart-router-events/ )
但這樣的路由定義模式,會限制專案的檔案結構,因為頁面檔案需統一放在 pages 資料夾中,而這個 route 相關的 /components
、/utils
、/lib
等必須放在 pages 資料夾外。
App Router 的 routing system 則改成,根目錄或 /src
中會有一個 /app
,/app
底下資料夾中若有 pages.js/.jsx/.ts/.tsx
,才會生成一個對應資料夾名稱的 route segment,而 page.tsx
則定義該 route segment 的 UI 。
舉例來說,/app/about/pages.js
會出現在 /about 中。而 /about
裡的其他檔案,除了幾個官方保留的特殊檔案,例如 pages.tsx
, layout.tsx
, loading.tsx
, error.tsx
等 ( 後續會詳細介紹 ),不會被影響到 URL;或是 /app/analytics
中沒有 pages.tsx
,就不會有 /analytics 這個 route segment。routing convention 後續會再介紹,這邊就先不細講。
( 圖片來源:https://nextjs.org/docs/app/building-your-application/routing/defining-routes )
此模式下即可支援不同專案架構,比方說以 features 或 route 做分類,將 /about 會用到的 components、styles、測試等檔案放在同個資料夾中。
除了提升了專案架構的靈活性外,上面有提到的一些特殊檔案也能讓開發者更簡單地提升網頁效能以及加強使用者體驗 ( ex: 避免不必要 re-render ),這部分就留到明天介紹囉!
今天的內容結束以前,想做一個小提醒:
根據官方說法,Pages Router 將可以與 App Router 共存,且目前沒有計畫要下架 Pages Router。所以假如目前專案是使用 Pages Router,想搬到 App Router 上的朋友,可以慢慢搬,不須著急。官方也有提供 migration guide,有需要的朋友可以參考連結。
謝謝大家耐心的閱讀,我們明天見!